﻿using System;
using System.Collections.Generic;
using System.Text;
using SlimDX;
using SlimDX.Direct3D9;

namespace Nimue.Materials
{
    class BaseSurfaceMaterial
    {
        #region Fields
        protected Color3 ambient, diffuse, specular, emissive;
        protected float specularPower, alpha;
        protected float data1, data2, data3, materialIndex;
        protected Texture diffuseTexture;
        protected bool twoSided, shadowReceiver, shadowCaster;
        protected String forceTechnique;
        #endregion

        #region Public Properties
        public Color3 Ambient
        {
            get { return ambient; }
            set { ambient = value; }
        }
        public Color3 Diffuse
        {
            get { return diffuse; }
            set { diffuse = value; }
        }
        public Color3 Specular
        {
            get { return specular; }
            set { specular = value; }
        }
        public Color3 Emissive
        {
            get { return emissive; }
            set { emissive = value; }
        }

        public float SpecularPower
        {
            get { return specularPower; }
            set { specularPower = value; }
        }
        public float Alpha
        {
            get { return alpha; }
            set { alpha = value; }
        }

        public Texture DiffuseTexture
        {
            get { return diffuseTexture; }
            set { diffuseTexture = value; }
        }

        public bool TwoSided
        {
            get { return twoSided; }
            set { twoSided = value; }
        }
        public bool ShadowReceiver
        {
            get { return shadowReceiver; }
            set { shadowReceiver = value; }
        }
        public bool ShadowCaster
        {
            get { return shadowCaster; }
            set { shadowCaster = value; }
        }

        public String ForceTechnique
        {
            get { return forceTechnique; }
            set { forceTechnique = value; }
        }
        #endregion

        #region Constructor
        public BaseSurfaceMaterial()
        {
            ambient = new Color3(1f, 1f, 1f);
            diffuse = new Color3(0f, 0f, 0f);
            specular = new Color3(0f, 0f, 0f);
            emissive = new Color3(0f, 0f, 0f);
            alpha = 1f;
            diffuseTexture = null;
            twoSided = false;
            forceTechnique = "";
        }

        public BaseSurfaceMaterial(Color3 ambient, Color3 diffuse, Color3 specular, Color3 emissive,
            float specularPower, float alpha, Texture diffuseTexture, bool twoSided, bool shadowReceiver, bool shadowCaster, String forceTechnique)
        {
            this.ambient = ambient;
            this.diffuse = diffuse;
            this.specular = specular;
            this.emissive = emissive;
            this.specularPower = specularPower;
            this.alpha = alpha;
            this.twoSided = twoSided;
            this.shadowReceiver = shadowReceiver;
            this.shadowCaster = shadowCaster;
            this.forceTechnique = forceTechnique;
        }
        #endregion

        #region ApplyToEffect
        public void ApplyToEffect(Effect effect)
        {
            effect.SetValue("AmbientColor", new Color4(ambient));
            effect.SetValue("DiffuseColor", new Color4(diffuse));
            effect.SetValue("SpecularColor", new Color4(specular));
            effect.SetValue("EmissiveColor", new Color4(emissive));

            effect.SetValue("SpecularPower", specularPower);
            effect.SetValue("Alpha", alpha);

            if (diffuseTexture != null)
                effect.SetTexture("DiffuseTexture", diffuseTexture);

            String technique = forceTechnique != "" ? forceTechnique : ("BaseSurface" + (diffuseTexture != null ? "Textured" : "") + (twoSided ? "TwoSided" : "") + (shadowReceiver ? "Shadowed" : ""));
            effect.Technique = technique;
        }
        #endregion
    }
}
